package org.apache.lucene.distributed.cl;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.URLClassLoader;
import java.util.Set;

import org.apache.bcel.Constants;
import org.apache.bcel.classfile.ClassParser;
import org.apache.bcel.classfile.Constant;
import org.apache.bcel.classfile.ConstantLong;
import org.apache.bcel.classfile.ConstantPool;
import org.apache.bcel.classfile.DescendingVisitor;
import org.apache.bcel.classfile.Field;
import org.apache.bcel.classfile.JavaClass;
import org.apache.lucene.distributed.RMIClasses;
import org.apache.lucene.distributed.RMIClasses.ClassAccept;

public class ClassDepends {
  DependencyVisitor dependencyVisitor;
  
  public static void main(String[] args) throws Exception {
    if (Thread.currentThread().getContextClassLoader() instanceof URLClassLoader) {
      URLClassLoader ucl = (URLClassLoader)Thread.currentThread().getContextClassLoader();
      System.out.println("ucl");
    }
    ClassDepends depends = new ClassDepends(null);
    //depends.run("org.apache.lucene.search.highlight.Highlighter");
    //depends.run("java.util.ArrayList");
    //Set<String> set = depends.run("org.apache.lucene.analysis.br.BrazilianAnalyzer");
    //System.out.println(set+"");
  }
  
  public ClassDepends(ClassAccept classAccept) {
    dependencyVisitor = new DependencyVisitor(classAccept);
  }
  
  public static Long getSerialVersionUID(String name, byte[] bytes) throws Exception {
    ClassParser classParser = new ClassParser(new ByteArrayInputStream(bytes), name);
    JavaClass javaClass = classParser.parse();
    for (Field field : javaClass.getFields()) {
      //System.out.println(field.getName());
      if (field.getName().equals("serialVersionUID")) {
        ConstantPool constantPool = field.getConstantPool();
        Constant c = constantPool.getConstant(field.getConstantValue().getConstantValueIndex());
        if (c.getTag() == Constants.CONSTANT_Long) {
          long l = ((ConstantLong) c).getBytes();
          return l;
        }
      }
    }
    return null;
  }
  
  public Set<String> run(String className) throws Exception {
    /**
    for (Field field : javaClass.getFields()) {
      System.out.println(field.getName());
      if (field.getName().equals("serialVersionUID")) {
        ConstantPool constantPool = field.getConstantPool();
        Constant c = constantPool.getConstant(field.getConstantValue().getConstantValueIndex());
        if (c.getTag() == Constants.CONSTANT_Long) {
          long l = ((ConstantLong) c).getBytes();
          System.out.println(l);
        }
      }
    }
    **/
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    String resource = RMIClasses.classToResource(className);
    InputStream input = classLoader.getResourceAsStream(resource);
    ClassParser classParser = new ClassParser(input, className);
    JavaClass javaClass = classParser.parse();
    DescendingVisitor traverser = new DescendingVisitor(javaClass, dependencyVisitor);
    traverser.visit();
    return dependencyVisitor.getDependencies();
  }
}
